﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using IWMAG.Core.Objects;

namespace IWMAG.Core.Messaging {
    public class Messenger {
        protected Level Level;
        protected Dictionary<Tuple<EventType, int, int>, List<int>> Subscriptions = new Dictionary<Tuple<EventType, int, int>, List<int>>();
        protected List<int> AlreadySent = new List<int>();

        public Messenger(Level l) {
            Level = l;
        }

        public void SendSubscription(Message msg, EventType type, int custom, int sender) {
            Tuple<EventType, int, int> index = Tuple.Create(type, custom, sender);

            if (Subscriptions.ContainsKey(index)) {
                foreach (int sub in Subscriptions[index]) {
                    if (!AlreadySent.Contains(sub)) {
                        AlreadySent.Add(sub);
                        Level[sub].ReceiveMessage(msg);
                    }
                }
            }
        }

        public void SendMessage(Message msg) {
            AlreadySent.Clear();
            SendSubscription(msg, EventType.Any, -1, -1);
            SendSubscription(msg, EventType.Any, -1, msg.Sender);

            if (msg.Type == EventType.Custom) {
                SendSubscription(msg, EventType.Custom, -1, -1);
                SendSubscription(msg, EventType.Custom, -1, msg.Sender);
                SendSubscription(msg, EventType.Custom, msg.CustomMessage, -1);
                SendSubscription(msg, EventType.Custom, msg.CustomMessage, msg.Sender);
            } else {
                SendSubscription(msg, msg.Type, -1, -1);
                SendSubscription(msg, msg.Type, -1, msg.Sender);
            }
        }

        public void Broadcast(Message msg) {
            foreach (GameObject obj in Level) {
                if (obj.Id != msg.Sender) {
                    obj.ReceiveMessage(msg);
                }
            }
        }

        public void SubscribeTo(int receive, EventType t) {
            SubscribeTo(receive, t, -1, -1);
        }

        public void SubscribeTo(int receive, EventType t, int sender) {
            SubscribeTo(receive, t, -1, sender);
        }

        public void SubscribeTo(int receive, int sender) {
            SubscribeTo(receive, EventType.Any, -1, sender);
        }

        public void SubscribeTo(int receive, int custom, int sender) {
            SubscribeTo(receive, EventType.Custom, custom, sender);
        }

        public void SubscribeTo(int receive, EventType t, int custom, int sender) {
            var key = Tuple.Create(t, custom, sender);
            if (!Subscriptions.ContainsKey(key)) {
                Subscriptions.Add(key, new List<int>());
            }

            Subscriptions[key].Add(receive);
        }
    }
}
